缘起

  • 想找一个开源技术点深入下去的,于是找到了redis,比较好的是,他有相应的学习曲线。
  • 全书第1遍用了3h19min的样子,20181117开始读的,20181123读完。还会继续阅读第2遍或第3遍,虽然原理性可能不太多,但我还没有很好的消化它,虽然这本书不是每个点都要了解,但还是要读到觉得能放下为止。
  • 下一本读《Redis实战》

内容

  • 目录 8/224

chap1 简介 11/224

1.1、历史与发展

  • 网站实时统计系统LLOOGG,创始人是意大利的Salvatore Sanfilippo
  • 是REmote DIctionary Server(远程字典服务器)的缩写。

1.2、特性

  • 1.2.1 存储结构
  • 1.2.2 内存存储与持久化

    • 数据都在内存中,程序退出后内存中的数据如何保存?
  • 1.2.3 功能丰富

    • 为每个键设置生存时间(Time To Live)
  • 1.2.4 简单稳定

    • HGET post:1 title // 读取键名为post:1 的散列类型键的title字段的值

chap2 准备 17/224

2.1、安装Redis

  • 2.1.1 在POSIX系统中安装

  • 2.1.2 在OS X系统中安装
  • 2.1.3 在Windows中安装

    • 比较麻烦

2.2、启动和停止Redis 11(21/224)

  • make后继续执行make install相应的6个命令会拷贝到/usr/local/bin目录下。
  • 2.2.1 启动Redis

    • 直接启动

      • redis-server,默认端口是6379;可以用port参数指定,即redis-server --port 6380
    • 通过初始化脚本启动

      • redis/utils/redis_init_script的脚本文件
      • 复制脚本到/etc/init.d目录中
  • 2.2.2 停止Redis

    • redis-cli SHUTDOWN

2.3、Redis命令行客户端

  • 2.3.1 发送命令

    • 参数模式

      • redis-cli -h 127.0.0.1 -p 6379
      • redis-cli PING
    • 交互模式

      • redis-cli后,再输入PINGECHO hi 无关大小写
  • 2.3.2 命令返回值

    • 状态回复
    • 错误回复
    • 整数回复
    • 字符串回复
    • 多行字符串回复

2.4、配置

  • redis-server /path/to/redis.conf 这个路径我没找到,只是解压目录下有个redis.conf文件
  • $redis> CONFIG SET命令在不重新启动Redis的情况下动态修改部分Redis配置

2.5、多数据库

  • 默认支付16个数据库select 0select 15
  • 这些数据库更像是一种命名空间;一个空Redis实例占用的内存只有1M左右。

chap3 入门 29/224

3.1、热身

  • 1、获得符合规则的键名列表

    • KEYS pattern patern支持glob风格通配符
    • set bar 1
    • keys * keys命令需要遍历Redis中的所有键,会影响性能,不建议用
  • 2、判断一个键是否存在

    • exists bar
    • exists no //返回值是(integer) 0
  • 3、删除键

    • del bar del命令不支付通配符
    • redis-cli keys "user:*" | xargs redis-cli del来实现删除
  • 4、获取键值的数据类型

    • type bar

3.2、字符串类型

  • 3.2.1 介绍

    • 一个字符串类型键允许存储的数据的最大容量是512MB
  • 3.2.2 命令

    • 1、复制与取值

      • set key hello
      • get key
    • 2、递增数字

      • INCR num
  • 3.2.3 实践

    • 1、文章访问量统计
    • 2、生成自增ID
    • 3、存储文章数据
  • 3.2.4 命令拾遗

    • 1、增加指定的整数

      • INCRBY bar 2
    • 2、减少指定的整数

      • DECR bar 只是递减,无法减多少
    • 3、增加指定浮点数

      • INCRBYFLOAT bar 2.7
    • 4、向尾部追加值

      • set key hello
      • append key " world!" // 返回的是总长度
    • 5、获取字符串长度

      • STRLEN key
    • 6、位操作 lionel这部分没看

3.3、散列类型

  • 3.3.1 介绍

    • 一个散列类型键可以包含至多2的32次方-1个字段
  • 3.3.2 命令

    • 1、赋值与取值

      • HSET car price 500
      • HSET car name BMW
      • HGET car name
      • 需要同时设置多个字段的值时,可以使用HMSET命令
      • HMGET car price name // 同时获得多个字段的值
      • HGETALL car // 想获取键中所有字段和这段值都不知道键中有哪些字段时
    • 2、判断字段是否存在

      • HEXISTS car model
    • 3、当字段不存在时赋值

      • HSETNX // 是原子操作,不用担心竞态条件
    • 4、增加数字

      • HINCRBY person score 60 // person键不存在,会创建该键并默认score字段在执行命令前的值为“0”。返回值是60
      • HINCRBY person score 1 // 因为存在了,所以返回值是61
    • 5、删除字段

      • 'HDEL'
  • 3.3.3 实践 lionel也没怎么好好看

    • 1、存储文章数据
    • 2、存储文章缩略名
  • 3.3.4 命令拾遗

    • 1、只获取字段名或字段值

      • HKEYS car
      • HVALS car
    • 2、获取字段数量

      • HLEN car

3.4、列表类型

  • 3.4.1 介绍

    • 一个列表(List)类型键可以包含至多2的32次方-1个元素
  • 3.4.2 命令

    • 1、向列表两端增加元素

      • LPUSH numbers 1 // 返回列表的长度 1
      • RPUSH numbers 0 -1 // 返回列表的长度 3
    • 2、从列表两端弹出元素

      • LPOP numbers
      • RPOP numbers
    • 3、获取列表中元素的个数

      • HLEN numbers
    • 4、获取列表片断

      • LRANGE numbers 0 2 // 获取一个区间的数据
    • 5、删除列表中指定的值

      • LREM numbers 0 -1 // count=0,删除所有“-1”的元素
      • LREM numbers -1 // count<0,从列表右边开始删除第1个元素;cout>0时,从左边删
  • 3.4.3 实践 lionel没怎么看

    • 1、存储文章ID列表
    • 2、存储评论列表
  • 3.4.4 命令拾遗

    • 1、获得/设置指定索引的元素值

      • LINDEX numbers 0
      • LSET numbers 1 7
    • 2、只保留列表指定片段

      • LRANGE numbers 0 -1
    • 3、向列表中插入元素

      • LINSERT numbers AFTER 7 3
      • LINSERT numbers BEFORE 2 1
    • 4、将元素从一个列表转到另一个列表

      • RPOPLPUSH

3.5、集合类型

  • 3.5.1 介绍

    • 一个集合(set)类型键可以包含至多2的32次方-1个字符串
  • 3.5.2 命令

    • 1、增加/删除元素

      • SADD letters a b c // 返回增加的个数 3
      • SREM letters c d // 返回删除的个数1,因为d本身就不存 在
    • 2、获得集合中的所有元素

      • SEMBERS letters
    • 3、判断元素是否在集合中

      • SISMEMBER letters a
    • 4、集合间运算

      • SDIFF
      • SINTER
      • SUNION
  • 3.5.3 实践

    • 1、存储文章标签
    • 2、通过标签搜索文章
  • 3.5.4 命令拾遗

    • 1、获得集合中元素个数

      • SCARD letters
    • 2、进行集合运算并将结果存储

      • SINTERSTORE
    • 3、随机获得集合中的元素

      • SRANDMEMBER letters
    • 4、从集合中弹出一个元素

      • SPOP letters

3.6、有序集合类型

  • 3.6.1 介绍

    • 有序集合与链表的异同
  • 3.6.2 命令

    • 1、增加元素

      • ZADD scoreboard 89 Tom 67 Peter 100 David
    • 2、获得元素的分数

      • ZSCORE scoreboard Tom 69/224 lionel 没怎么读
  • 3.6.3 实践

    • 1、实现按点击量排序
    • 2、改进按时间排序
  • 3.6.4 命令拾遗

    • 1、获得集合中元素的数量

      • ZCARD scoreboard
    • 2、获得指定分数范围内的元素个数
    • 3、删除一个或多个元素
    • 4、按照排名范围删除元素 lionel也没怎么看呢

chap4 进阶 67(77/224)

4.1、事务

  • 4.1.1 概述

    • MULTI命令告诉Redis,下面的命令属于事务。
  • 4.1.2 错误处理

    • 语法错误 直接不执行,返回错误码
    • 运行错误 不支持回滚功能,只能将数据库复原到之前的状态
  • 4.1.3 WATCH命令介绍

    • WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行
    • UNWATCH取消监控

4.2、过期时间

  • 4.2.1 命令介绍

    • SET session:29e3d uid1314
    • EXPIRE session:29e3d 900 // 让session:29e3d键在15分钟后被删除。 EXPIRE命令设置一个键的过期时间,到时期后Redis会自动删除它
    • TTL session:29e3d // session:29e3d键的剩余时间
    • PERSIST session:29e3d // 取消session:29e3d键的过期时间设置
  • 4.2.2 实现访问频率限制之一

    • 限制每分钟每个用户最多只能访问100个页面。
  • 4.2.3 实现访问频率限制之二
  • 4.2.4 实现缓存

    • 修改配置文件的maxmemory参数,限制Redis最大可用内存大小,超出限制时Redis会依据maxmemory-policy参数指定的策略来删除不需要的键,直到Redis占用的内存小于指定内存。

4.3、排序

  • 4.3.1 有序集合的集合操作
  • 4.3.2 SORT命令
  • 4.3.3 BY参数

    • SORT sortbylist BY somkey->somefield:* // *只能在->符号前面才有用,否则只会被当作字段名本身
  • 4.3.4 GET参数

    • SORT tag:ruby:posts BY post:*->time DESC post:*->title // GET参数不影响排序,作用是使SORT命令的返回结果不再是元素自身的值,而是GET参数中指定的键值。
  • 4.3.5 STORE参数

    • SORT tag:ruby:posts BY post:*->time DESC GET post:*->title GET post:*->time GET # STORE sort.result // 保存排序结果,默认是直接返回排序结果的
  • 4.3.6 性能优化

    • SORT的时间复杂度是O(n+mlog(m))
    • 使用SORT命令时有几点注意:

      • 尽可能减少待排序的数据(N尽可能小)
      • 使用LIMIT参数只获取需要的数据(使M尽可能小)
      • 如果要排序的数据量较大,尽可能使用STORE参数将结果缓存

4.4、消息通知

  • 4.4.1 任务队列
  • 4.4.2 使用Redis实现任务队列
  • 4.4.3 优先级队列 lionel没好好看,以及4.4到目前
  • 4.4.4 “发布/订阅”模式

    • PUBLISH channel.2 hi // 向channel.2说一声“hi” 发布者
    • SUBSCRIBE chanel.2 // 订阅者
  • 4.4.5 按照规则订阅

    • PSUBSCRIBE channel.?* // 订阅指令的规则,支持glob风格通配符

4.5、管道

4.6 节省空间

  • 4.6.1 精简键名和键值
  • 4.6.2 内部编码优化 lionel没好好看

    • 0、
    • 1、字符串类型

chap5 实践 103(113/224)

5.1、PHP与Redis

  • 5.1.1 安装

    • 解压后放入项目目录中,引用autoload.php文件require './dir/autoload.php' 假设在dir目录下,后面会用到
  • 5.1.2 使用方法

    • 创建一个连接

      • $redis = new dir\Client();
      • $redis = new dir\Client(arry('scheme'=>'tcp','host'=>'127.0.0.1','port'=>6379,));
      • echo $redis->get('foo');
  • 5.1.3 简便用法
  • 5.1.4 实践:用户注册登录功能

5.2、Ruby与Redis

  • 5.2.1 安装

    • gem install redis安装新版的redis-rb
  • 5.2.2 使用方法
  • 5.2.3
  • 5.2.4

5.3、Python与Redis

  • 5.3.1 安装

    • pip install redis
  • 5.3.2 使用方法

    • import redis // 引入redis-py
  • 5.3.3 简便用法

    • 1、HMSET/HGETALL
    • 2、事务和管道
  • 5.3.4 实践:在线的好友

5.4、Node.js与Redis

  • 5.4.1 安装

    • npm install ioredis
  • 5.4.2 使用方法

    • 加载ioredis模块var Redis = require('ioredis');
  • 5.4.3 简便用法

    • 1、HMSET/HGETALL
    • 2、事务
    • 3、“发布/订阅”模式
  • 5.4.4 实践:IP地址查询

chap6 脚本 131(141/224)

6.1、概览

  • 6.1.1 脚本介绍

    • 允许开发者使用Lua语言编写脚本传到Redis中执行。
    • 脚本的好处:

      • (1)减少网络开销
      • (2)原子操作
      • (3)复用
  • 6.1.2 实例:访问频率限制

6.2、Lua语言

  • 6.2.1 Lua语法

    • 数据类型
    • 变量
    • 注释
    • 赋值
    • 操作符
    • if语句
    • 循环语句
    • 表类型
    • 函数
  • 6.2.2 标准库

    • String库
    • Table库
    • Math库
  • 6.2.3 其他库

    • cjson库
    • cmsgpack库

6.3、Redis与Lua

  • 6.3.1 在脚本中调用Redis命令
  • 6.3.2 从脚本中返回值
  • 6.3.3 脚本相关命令

    • 1、EVAL命令
    • 2、EVALSHA命令
  • 6.3.4 应用实例

    • 1、同时获取多个散列类型键的键值
    • 2、获利并删除有序集合中分数最小的元素
    • 3、处理JSON

6.4、深入脚本

  • 6.4.1 KEYS与ARGV
  • 6.4.2 沙盒与随机数
  • 6.4.3 其他脚本相关命令

    • 1、将脚本加入缓存:SCRIPT LOAD
    • 2、判断脚本是否已经被缓存:SCRIPT EXISTS
    • 3、清空脚本缓存:SCRIPT FLUSH
    • 4、强制终止当前脚本的执行:SCRIPT KILL
  • 6.4.4 原子性和执行时间

chap7 持久化 157(167/224)

7.1、RDB方式

  • 0、

    • 通过快照(snapshotting)完成的。当符合一定条件的Redis会自动将内存中的所有数据生成一份副本并存储在硬盘上,这个过程即为“快照“。
    • 在以下情况对数据进行快照:

      • 根据配置规则进行自动快照
      • 用户执行SAVE或BGSAVE命令
      • 执行FLUSHALL命令
      • 执行复制(replication)时
  • 7.1.1 根据配置规则进行自动快照
  • 7.1.5 快照原理

    • 在执行fork时OS会使用写时复制(copy-on-write)策略,即fork函数发生的一刻子进程共享同一内存数据
    • 所以新的RDB文件存储的是执行fork一刻的内存数据。
    • 我们通过定时备份RDB文件来实现Redis数据库备份

7.2、AOF方式

  • 7.2.1 开启AOF

    • appendonly yes**通过手工开启,默认没有开启(AOF append only file)
  • 7.2.2 AOF的实现
  • 7.2.3 同步硬盘数据

    • 操作系统的缓存机制,数据并没有真正地写入硬盘,而是进入了系统的硬盘缓存。在默认情况下系统每30秒会执行一次同步操作,以便将硬盘缓存中的内容真正地写入硬盘。
    • appendfsync everysec // 采用everysec规则

chap8 集群 165(175/224)

8.1、复制

  • 8.1.1 配置

    • $ redis-server --port 6380 --slaveof 127.0.0.1 6379
    • SALVEOF命令会停止和原来数据库的同步转而和新数据库同步。
  • 8.1.2 原理
  • 8.1.3 图结构
  • 8.1.4 读写分离与一致性

    • 一主多从的结构很适合读多写少的场景,主数据库只进行写操作,从数据库负责读操作。
  • 8.1.5 从数据库持久化
  • 8.1.6 无硬盘复制
  • 8.1.7 增量复制

8.2、哨兵

  • 8.2.1 什么是哨兵
  • 8.2.2 马上上手
  • 8.2.3 实现原理

    • 一个哨兵节点可以同时监控多个Redis主从系统,只需要提供多个sentinel monitor配置即可。
  • 8.2.4 哨兵的部署

    • 哨兵以独立进程的方式对一个主从系统进行监控

8.3、集群

  • 8.3.1 配置集群

    • 需要将每个数据库节点的cluster-enabled配置选项打开即可。
  • 8.3.2 节点的增加
  • 8.3.3 插槽的分配
  • 8.3.4 获取与插槽对应的节点
  • 8.3.5 故障恢复

chap9 管理 193(203/224)

9.1、安全

  • 9.1.1 可信的环境
  • 9.1.2 数据库密码
  • 9.1.3 命名命令

9.2、通信协议

  • 9.2.1 简单协议

    • 适合在telnet程序中和Redis通信。
  • 9.2.2 统一请求协议

9.3、管理工具

  • 9.3.1 redis-cli

    • 耗时命令日志

      • redis> SLOWLOG GET
    • 命令监控

      • redis> MONITOR
  • 9.3.2 phpRedisAdmin
  • 9.3.3 Rdbtools

附录 203(213/224)

附录A

  • A.1 REDIS_CMD_WRITE
  • A.2 REDIS_CMD_DENYOOM
  • A.3 REDIS_CMD_NOSCRIPT

附录B

附录C CRC16 实现参考

收获

履历

  • 20181117从头开始看到3.2.4节(1-37/224),用时1h16min。不太理解的地方

    • (1)用命令行配置启动;(2)redis配置; 虽然照着会做,但知识点上没有融汇贯通
  • 20181119从3.2.4看到4.1.2(37-80/224),用时1h02min。差不多我只能坚持看1小时书

    • 中间有几个地方跳过没好好看,后期要补上,主要是单纯的用命令,不知道场景在哪,可能属于基础吧,还是需要熟悉。
    • 要确认各个类型的区别,以及知道他们的优缺点。
  • 20181120从4.1.2看到5.3.1(80-126/224),用时40min

    • 在4.4消息通知方面没怎么看,包括4.6节省空间方面。
    • 其它方面的知识呢,差不多都能理解。可以搜搜面试指南来查漏或夯实知识
  • 20181121从5.3.1看到7.1.4(126-169/224),用时21min。其实没怎么看,就是过了下结构

    • 毕竟第chap6的Lua和chap5实践,都需要搭建环境去跑的,算是个大概了解吧,估计后期会选用Python进行实践,因为《Redis实战》用的是这个。
    • chap7持久化开了个头,因为前期还搜了部分知道,看起来不觉得费劲。
  • 20181123从7.1.5看到结束(169-224/224),用时26min。也没有过多学习新知识,就是看个大概。

    • 了解了下AOF方式。
    • 集群的话,面试环境可能会在复制这部分有些问题要问,自己也有点感触,但哨兵和集群,可能在架构或配置时要用。
    • chap9管理的话,只是作了部分的了解。

im天行
35 声望198 粉丝